        TITL DAI FIRMWARE 2E7FC-2EA0A  V1.1
        ORG   :E7FC
*
*
*
**************************
* MOVE POINTER UP / DOWN *
**************************
*
* Subroutine of SDRAW (2E71B).
* Takes a pointer to screen and moves it up or
* down the screen a number of lines. The move
* direction depends on DIRN1 (00BF).
*
* Entry: HL: Pointer.
*        B:  Number of lines.
* Exit:  HL: updated.
*        AFBCDE preserved.
*
UPDTP   PUSH  PSW
        PUSH  D
        PUSH  H
        LDA   :0098     Get number bytes/line
        MOV   L,A       ) Store it in HL
        MVI   H,:00     )
        MOV   A,B       Get nr of lines
        CALL  :EB46     Calc total length in HL
        LDA   :00BF     Get Y-direction
        ORA   A         Test if up or down
        CNZ   :E706     If down:  Calc 2-compl of HL
        POP   D
        DAD   D         Update pntr
        CALL  :EAC7     Into or out archive area
        POP   D
        POP   PSW
        RET
*
*****************************************
* FILL A RECTANGULAR AREA ON THE SCREEN *
*****************************************
*
* Fills an arbitrary rectangle with a given colour.
*
* The middle of the rectangle is filled first, then
* the left and then the right edge vertical strips.
* The coordinates are given inclusively.
* The rectangle is filled in the same order, which
* ever order the parameters are given in.
*
* Entry: B,DE: Y,X coordinate of one corner.
*        C,HL: Idem of the opposite corner.
*        A:    Colour.
* Exit:  ABCDEHL preserved.
*        CY=0: OK.
*        CY=1: A contains error code.
*
SFILL   ORA   A
        PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
FIL10   CALL  :E83A     Check arguments, get colour
        MOV   D,A       Get Y-coord left corner
        LDA   :00BF     ) Check if Y invert
        ORA   A         )
        MOV   A,D
        JZ    :E82A     Jump if no Y-inversion
        SUB   E         Y-pos bottom left
FIL20   PUSH  H         Save X-size
        CALL  :EBB9     Get memory address
        MOV   A,C
        ANI   :07
        MOV   C,A       Offset in C
        MOV   B,E       Height in B
        POP   D         Width in DE
        CALL  :EAF7     Fill block
        JMP   :E138     Popall, ret
*
*******************************
* CHECK ARGUMENTS, GET COLOUR *
*******************************
*
* Checks the arguments given to a entry point and
* sets up the colour variables. Swops order of two
* points given if necessary.
*
* Entry: ABCDEHL: See SFILL.
*        All registers and a returnaddr on stack.
* Exit:  CY=0: O.K.:
*              A,BC:  Set to left corner.
*              DE,HL: Set to Y,X lengths of line.
*              DIRN1: <>0 if Y-direction negative.
*        CY=1: Error report:
*              A=1:   Off screen.
*              A=2:   Colour not available.
*
ARGCHK  CALL  :E9C3     Set up colour variables
        JC    :E875     Jump if colour not av.
        CALL  :EB7A     Check if room available
        JC    :E87F     Jump if not
        PUSH  B
        MOV   C,B       Y-coord one point in C
        XCHG
        CALL  :EB7A     Check if room available
        XCHG
        POP   B
        JC    :E87F     Jump if not
        CALL  :E6FB     Compare HL-DE
        JNC   :E85D     Right most point to C,HL
 REM
* Swop Y-coord.:
 REM
        XCHG
        PUSH  PSW
        MOV   A,B       )
        MOV   B,C       ) Swop 2 points
        MOV   C,A       )
        POP   PSW
*
ARC10   CALL  :E6F2     Calc horizontal length
        PUSH  D         Save X-pos left corner
        MOV   A,C
        SUB   B
        MVI   D,:00     Clear Y-invert flag
        JNC   :E86B     Jump if end above start
        CMA
        INR   A
        DCR   D
*
ARC20   MOV   E,A       Get vertical length
        MOV   A,D
        STA   :00BF     Set Y-invert flag
        MVI   D,:00
        MOV   A,B       Get Y-pos left corner
        POP   B         Get X-pos left corner
        RET
 REM
* If colour error:
 REM
ARC90   MVI   A,:02     Error colour not available
ARC98   POP   H
        POP   H
        POP   D
        POP   B
        INX   SP
        INX   SP
        STC             Return error
        RET
 REM
* If off screen error:
 REM
ARC99   MVI   A,:01     Error off screen
        JMP   :E877     Abort
*
*******************************************
* ASK COLOUR OF A POINT ON THE SCREEN AND *
*     ASK SIZE OF THE GRAPHICS SCREEN     *
*******************************************
*
* Aks the colour of a given point on the screen
* and the size of the graphics area of the screen.
*
* Entry: C,HL: Y,X coordinate of the dot required.
* Exit:  CY=0: O.K.:
*              A:    Colour at requested point.
*              B,DE: Max. coordinates of the
*                    graphics area.
*              CHL preserved.
*        CY=1: A:    Error code.
*              BCDEHL preserved.
*
SSCRN   PUSH  H
        PUSH  B
        CALL  :EB7A     Check if room available
        JC    :E8D8     Jump if not
        MOV   A,L
        ANI   :07
        PUSH  PSW       Remember field offset
        MOV   A,C       )
        MOV   B,H       ) Coord in A,B,C
        MOV   C,L       )
        CALL  :EBB9     Get address of point
        LDA   :009D     Get current screen mode
        RAR
        RAR
        JC    :E8B8     Jump if 4-colour mode
 REM
* If 16-colour mode:
 REM
        CALL  :E8F6     Colours to buffer
        LXI   H,:00A3   Addr SCXBUF
        POP   PSW
        CALL  :E701     Calc addr in buffer
        MOV   A,M       Get colour for reqd blob
SSC10   LHLD  :0096     Get nr of graphics lines
        MOV   B,L
        DCR   B         lobyte -1 in B
        LHLD  :0094     Get nr of hor. blobs
        DCX   H         -1
        XCHG            in DE
        POP   H
        MOV   C,L       Y-coord in C
        POP   H         X-coord in HL
        ORA   A         CY=0
        RET
 REM
* If 4-colour mode:
 REM
SSC30   MOV   D,M       )
        DCX   H         ) Get screen data of
        MOV   E,M       ) point in DE
        POP   PSW
        MOV   C,A       Field offset in C
        MVI   B,:01
        CALL  :EBE1     Set mask for bits
        LXI   H,:009E   Pntr to COLORG colours
        MOV   A,B
        ANA   D         Test top bit result
        JZ    :E8CC     Skip if 0
        INX   H
        INX   H
SSC40   MOV   A,B
        ANA   E         Test bottom bit result
        JZ    :E8D2     Skip if 0
        INX   H
SSC50   MOV   A,M       Get result from table
        ANI   :0F       Colour bits only
        JMP   :E8A9
 REM
* If off screen:
 REM
SSC99   POP   H
        POP   B
        MVI   A,:01     Error 'off screen'
        STC
        RET
*
******************
* UPDATE A FIELD *
******************
*
* Given a mask of bits to be changed, a colour to
* set them to and a memory address where the field
* starts. This routine reads, updates and replaces
* a field.
*
* Entry: HL: Memory address of start of field.
*        B:  Mask of bits to be changed.
*        C:  Colour to change to (hinibble).
* Exit:  All registers preserved.
*
SUPDTE  PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        MOV   A,C       )
        RRC             )
        RRC             ) Move hinibble C into
        RRC             ) lonibble
        RRC             )
        MOV   C,A       )
        PUSH  B
        CALL  :E8F6     Get current state of screen
        POP   B
        CALL  :E9B2     Change as required
        POP   H
        PUSH  H
        JMP   :C6BA     Set up screen bits for
 REM mode 1
*
        DATA  :FF
*
**********************************
* LOAD BUFFER SCXBUF FROM SCREEN *
**********************************
*
* Takes 2 bytes of screen info in 16-colour mode
* and places them in SCXBUF (00A3-AB) in 'standard
* form'.
*
* Entry: HL: Points to 1st byte of info on screen.
* Exit:  All registers corrupted.
*
SSFM    INX   H
        MOV   A,M       Get previous colour byte
        ANI   :0F       Background only
        MOV   C,A       Previous background in C
        DCX   H
        MOV   D,M       Select byte in D
        DCX   H
        MOV   E,M       Colour byte in E
        DCX   H
        PUSH  H         Save pntr to next field
 REM select byte
        MOV   A,E       Colour byte in A
        ANI   :F0       )
        RRC             ) Foreground colour
        RRC             ) in lonibble
        RRC             )
        RRC             )
        MOV   B,A       Foreground colour in B
        LXI   H,:00A3   Addr SCXBUF
        MOV   A,D       Get bit mask
        MVI   D,:08     8 bytes to set
SSF10   RLC
        MOV   M,C       Set background
        JNC   :E91E     Jump if background
        MOV   M,B       Else: set foreground
        PUSH  PSW
        MOV   A,E       Get colour byte
        ANI   :0F       Background colour only
        MOV   C,A       Background is current BG
        STA   :00AC     Store it as colour carried
 REM out to next field
        POP   PSW
SSF20   INX   H         Next pos in SCXBUF
        DCR   D         Count -1
        JNZ   :E90F     Loop if more bits
        POP   B         Get pntr to next field
 REM select byte
        MVI   M,:FF     Flag no carry out in SBGOU
        LDAX  B         Get next select byte
SSF30   INR   M         Set 'carry out' flag
        RLC
        JNC   :E927     Loop counting carry out
        RET
*
*********************************
* SET UP SCREEN BITS FOR MODE 1 *
*********************************
*
* Takes the 8 blobs represented in standard form
* in SCXBUF, and tries to represent them in a way
* which the screen requires for mode 1.
* Up to 2 colours is easy. 3 require to attempt
* to carry in the 1st colour from the previous
* byte.
*
* Entry: HL: Points to 1st of the 2 screen bytes.
* Exit:  Screen will be updated as well as
*        possible.
*        All registers preserved.
*
*SBF00
SBFM    INX   H
        MOV   A,M
        ORI   :80
        MOV   E,A       Prev background in E
        MVI   D,:00     Init bit map
        LXI   H,:00A3   Addr SCXBUF
        NOP
        NOP
SBF05   LDA   :00AB     Get flag for colour carried
 REM out
        ORA   A
        JZ    :E945     Jump if no carry out
        LDA   :00AC     Get colour carried out
        ORI   :80       Set msb=1
SBF10   MOV   C,A       Background colour in C
        MOV   A,M
        INX   H
        MOV   B,A       Set 1st blob as FG colour
        MOV   A,D       )
        STC             ) 1 bit in right end bit
        RAL             ) mask
        MOV   D,A       )
SBF30   MOV   A,M
        INX   H
        CMP   B         Is next blob FG colour ?
        STC
        JZ    :E961     Jump if true
        ORI   :80
        CMP   C         Test if same as BG ?
        JZ    :E960     Jump if true
        DCR   C
        INR   C
        JM    :E986     No luck if BG used already
        MOV   C,A       Else set it to BG
SBF40   ORA   A
SBF45   MOV   A,D       )
        RAL             ) New bit in bottom of mask
        MOV   D,A       )
SBF50   MOV   A,L
        CPI   :AB       End of buffer reached ?
        JNZ   :E94D     Loop until all set up
        POP   H
        PUSH  H
        INX   H
        MOV   A,E
        ANI   :0F
        MOV   E,A       Only lonibble of E
        MOV   A,M
        ANI   :F0       Only hinibble of M
        ORA   E
        MOV   M,A       Add both nibbles together
        DCX   H
        MOV   A,B
        ADD   A
        ADD   A
        ADD   A
        ADD   A         FG colour to top bits
        MOV   B,A
        MOV   A,C
        ANI   :0F       Low nibble only
        ORA   B
        MOV   M,D       Bit map from D
        DCX   H
        MOV   M,A       Colours from E
SBF90   POP   H
        RET
 REM
* 3 colours needed:
 REM
SBF80   MOV   A,E
        ORA   A
        JP    :E984     Jump if tried BG carried in
        ANI   :0F       Previous BG
        CMP   B         Test against 1st blob colour
        POP   H
        PUSH  H
        INX   H
        INX   H
        MOV   A,M       Get bit map
SBF83   STC
        RAL
        JNC   :E993     Ignore leading BG
        JZ    :E9A1     Jump if colour matches
 REM anyway
        INR   A
        JNZ   :E984     No good if BG used
 REM
* Background not in use:
 REM
        MOV   E,B       Set previous BG
        NOP
SBF85   LXI   H,:00A3   Addr SCXBUF
        MVI   D,:00     Init D
        NOP
        MOV   C,D       and C (BG free)
SBF88   MOV   A,M       Get byte from SCXBUF
        CMP   B
        JNZ   :E939     Jump if blob not old BG
 REM colour
        NOP
        INX   H
        JMP   :E9A8     Next blob
*
************************
* UPDATE BUFFER SCXBUF *
************************
*
* Takes a set of 'update instructions' in BC and
* sets various bytes in SCXBUF accordingly.
*
* Entry: BC: Instructions.
* Exit:  All registers corrupted.
*
SUDCH   LXI   H,:00A3   Addr SCXBUF
        MOV   A,B       Mask in A
        MVI   B,:08     8 byte to be done
SUD10   RLC             Bit from mask into CY
        JNC   :E9BD     Jump if bit = 0
        MOV   M,C       Else: C into SCXBUF
SUD20   INX   H
        DCR   B
        JNZ   :E9B8     Next byte if not ready
        RET
*
***************************
* SET UP COLOUR VARIABLES *
***************************
*
* Entry: A: Colour.
* Exit:  CY=1: Colour not available.
*        CY=0: O.K.: ABCDEHL preserved.
*
COLSU   ORA   A
        PUSH  PSW
        PUSH  B
        MOV   C,A       Colour in C
        XRA   A
        STA   :00C1     Reset animate flag
        LDA   :009D     Get current screen mode
        RAR
        RAR
        JNC   :E9FD     Jump if 16-colour
 REM
* If 4-colour:
 REM
        MOV   A,C       Get colour
        CPI   :10
        JC    :E9E1     Jump if < 16
        CALL  :D886     Check if >= 20. Set 00C1
 REM for 4-colour animate if not
CSU04   ANI   :03
        JMP   :E9E7     Bottom 3 bits only
CSU05   CALL  :EB9B     Find colour in COLORG reg
 REM (2 bit code)
        JNC   :EA07     Jump if colour not av.
CSU08   MVI   B,:00
        CPI   :02
        JC    :E9EF     Jump if top bit 0
        DCR   B         Set 00/FF on top bit
CSU10   ANI   :01
        CMA
        INR   A         Set 00/FF on bottom bit
CSU30   STA   :00C2     )
        MOV   A,B       ) Store details for colour
        STA   :00C3     ) reqd
        POP   B
        POP   PSW
        RET
 REM
* If 16-colour:
 REM
CSU40   MOV   A,C       Get colour
        ADD   A         )
        ADD   A         ) SHL 8
        ADD   A         )
        ADD   A         )
        MVI   B,:FF
        JMP   :E9F3     Store details for colour
 REM reqd
 REM
* If colour not found:
 REM
CSU99   POP   B
        POP   PSW
        CMC             Quit; 'colour not available'
        RET
*
*
*
        UNL
SBF00   EQU SBFM
        LST
        END
